package expressions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import tester.*;
import tester.cobertura.Instrument;

/**
 * Title : BEVisitor
 * 
 * Javadoc Online at : http://www.ccs.neu.edu/home/ada2358/Doc/Satisfiability/index.html
 * @author Adam Blackwell
 * @version 1.0
 * @since April 2nd 2009
 */
@Example @Instrument
public class BEVarVisitor implements BEVisitor<HashMap<String, Boolean>> {
  /* Fields */
  public HashMap<String, Boolean> vars;
  
  /**
   * Other Constructor:
   * @param vars
   */
  public BEVarVisitor(HashMap<String, Boolean> vars) {
    super();
    this.vars = vars;
  }
  
  /**
   * Default Constructor :
   */
  public BEVarVisitor() {
    super();
    this.vars = new HashMap<String, Boolean>();
  }
  
  /* (non-Javadoc)
   * @see expressions.BEVisitor#forAnd(expressions.BE, expressions.BE)
   */
  @Override public HashMap<String, Boolean> forAnd(BE left, BE right) {
    HashMap<String, Boolean> set = left.accept(this);
    set.putAll(right.accept(this));
    return set;
  }
  
  /* (non-Javadoc)
   * @see expressions.BEVisitor#forNot(expressions.BE)
   */
  @Override public HashMap<String, Boolean> forNot(BE be) {
    // TODO Auto-generated method stub
    return be.accept(this);
  }
  
  /* (non-Javadoc)
   * @see expressions.BEVisitor#forOr(expressions.BE, expressions.BE)
   */
  @Override public HashMap<String, Boolean> forOr(BE left, BE right) {
    // TODO Auto-generated method stub
    HashMap<String, Boolean> set = left.accept(this);
    set.putAll(right.accept(this));
    return set;
  }
  
  /* (non-Javadoc)
   * @see expressions.BEVisitor#forVar(expressions.BE)
   */
  @Override public HashMap<String, Boolean> forVar(BE be) {
    HashMap<String, Boolean> set = new HashMap<String, Boolean>();
    set.put(((Var)be).getName(), ((Var)be).isValue());
    return set;
  }
  
  
//  /* Fields */
//  public TreeSet<Var> vars;
//  
//  /**
//   * Other Constructor:
//   * @param vars
//   */
//  public BEVarVisitor(TreeSet<Var> vars) {
//    super();
//    this.vars = vars;
//  }
//  
//  /**
//   * Default Constructor :
//   */
//  public BEVarVisitor() {
//    super();
//    this.vars = new TreeSet<Var>();
//  }
//  
//  /* (non-Javadoc)
//   * @see expressions.BEVisitor#forAnd(expressions.BE, expressions.BE)
//   */
//  @Override public TreeSet<Var> forAnd(BE left, BE right) {
//    // TODO Auto-generated method stub
//    TreeSet<Var> set = left.accept(this);
//    set.addAll(right.accept(this));
//    return set;
//  }
//  
//  /* (non-Javadoc)
//   * @see expressions.BEVisitor#forNot(expressions.BE)
//   */
//  @Override public TreeSet<Var> forNot(BE be) {
//    // TODO Auto-generated method stub
//    return be.accept(this);
//  }
//  
//  /* (non-Javadoc)
//   * @see expressions.BEVisitor#forOr(expressions.BE, expressions.BE)
//   */
//  @Override public TreeSet<Var> forOr(BE left, BE right) {
//    // TODO Auto-generated method stub
//    TreeSet<Var> set = left.accept(this);
//    set.addAll(right.accept(this));
//    return set;
//  }
//  
//  /* (non-Javadoc)
//   * @see expressions.BEVisitor#forVar(expressions.BE)
//   */
//  @Override public TreeSet<Var> forVar(BE be) {
//    // TODO Auto-generated method stub
//    if (!this.vars.contains(be)) {
//      vars.add((Var) be);
//      return this.vars;
//    } else {
//      return vars;
//    }
//  }
  
  /* *************** *
   * Testing :       *
   * *************** */
   
  @TestMethod
  public void tests(Tester t) {
    BEVarVisitor varVisit = new BEVarVisitor();
    BE be1 = new And(new Var("x", true), new Var("y", false));
    BE be2 = new And(new Var("x", true), 
                      new Or(new Not(new Var("z", true)),
                             new Var("y", false)));
    BE be3 = new And(new Var("x", true), 
                      new Or(new Not(new Var("z", true)),
                             new Var("y", false)));
    t.checkExpect(be1.accept(varVisit).size(), 2);
    t.checkExpect(be2.accept(varVisit).size(), 3);
    t.checkExpect(be3.accept(varVisit).size(), 3);
  }
}
